(in-package #:org.shirakumo.fraf.trial.nxgl)

(define-global +keyword-string-map+
    (let ((table (make-hash-table :test 'eql)))
      ;; Emulating a basic ANSI-US layout.
      (loop for (k v v2) in '((:a "a" "A")
                              (:b "b" "B")
                              (:c "c" "C")
                              (:d "d" "D")
                              (:e "e" "E")
                              (:f "f" "F")
                              (:g "g" "G")
                              (:h "h" "H")
                              (:i "i" "I")
                              (:j "j" "J")
                              (:k "k" "K")
                              (:l "l" "L")
                              (:m "m" "M")
                              (:n "n" "N")
                              (:o "o" "O")
                              (:p "p" "P")
                              (:q "q" "Q")
                              (:r "r" "R")
                              (:s "s" "S")
                              (:t "t" "T")
                              (:u "u" "U")
                              (:v "v" "V")
                              (:w "w" "W")
                              (:x "x" "X")
                              (:y "y" "Y")
                              (:z "z" "Z")
                              (:1 "1" "!")
                              (:2 "2" "@")
                              (:3 "3" "#")
                              (:4 "4" "$")
                              (:5 "5" "%")
                              (:6 "6" "^")
                              (:7 "7" "&")
                              (:8 "8" "*")
                              (:9 "9" "(")
                              (:0 "0" ")")
                              (:space " ")
                              (:minus "-" "_")
                              (:plus "=" "+")
                              (:left-bracket "[" "{")
                              (:right-bracket "]" "}")
                              (:pipe "\\" "|")
                              (:tilde "`" "~")
                              (:semicolon ";" ":")
                              (:quote "'" "\"")
                              (:backquote "`")
                              (:comma "," "<")
                              (:period "." ">")
                              (:slash "/" "?")
                              (:kp-divide "/")
                              (:kp-multiply "*")
                              (:kp-subtract "-")
                              (:kp-add "+")
                              (:kp-1 "1")
                              (:kp-2 "2")
                              (:kp-3 "3")
                              (:kp-4 "4")
                              (:kp-5 "5")
                              (:kp-6 "6")
                              (:kp-7 "7")
                              (:kp-8 "8")
                              (:kp-9 "9")
                              (:kp-0 "0")
                              (:kp-dot ".")
                              (:backslash "\\" "|")
                              (:kp-equal "=")
                              (:kp-decimal "."))
            do (setf (gethash k table) (cons v (or v2 v))))
      table))

(define-global +scan-code-keyword-map+
    (let ((array (make-array 256 :initial-element NIL)))
      (loop for (k v) in '((#x04 :a)
                           (#x05 :b)
                           (#x06 :c)
                           (#x07 :d)
                           (#x08 :e)
                           (#x09 :f)
                           (#x0a :g)
                           (#x0b :h)
                           (#x0c :i)
                           (#x0d :j)
                           (#x0e :k)
                           (#x0f :l)
                           (#x10 :m)
                           (#x11 :n)
                           (#x12 :o)
                           (#x13 :p)
                           (#x14 :q)
                           (#x15 :r)
                           (#x16 :s)
                           (#x17 :t)
                           (#x18 :u)
                           (#x19 :v)
                           (#x1a :w)
                           (#x1b :x)
                           (#x1c :y)
                           (#x1d :z)
                           (#x1e :1)
                           (#x1f :2)
                           (#x20 :3)
                           (#x21 :4)
                           (#x22 :5)
                           (#x23 :6)
                           (#x24 :7)
                           (#x25 :8)
                           (#x26 :9)
                           (#x27 :0)
                           (#x28 :enter)
                           (#x29 :escape)
                           (#x2a :backspace)
                           (#x2b :tab)
                           (#x2c :space)
                           (#x2d :minus)
                           (#x2e :plus)
                           (#x2f :left-bracket)
                           (#x30 :right-bracket)
                           (#x31 :pipe)
                           (#x32 :tilde)
                           (#x33 :semicolon)
                           (#x34 :quote)
                           (#x35 :backquote)
                           (#x36 :comma)
                           (#x37 :period)
                           (#x38 :slash)
                           (#x39 :caps-lock)
                           (#x3a :f1)
                           (#x3b :f2)
                           (#x3c :f3)
                           (#x3d :f4)
                           (#x3e :f5)
                           (#x3f :f6)
                           (#x40 :f7)
                           (#x41 :f8)
                           (#x42 :f9)
                           (#x43 :f10)
                           (#x44 :f11)
                           (#x45 :f12)
                           (#x46 :print-screen)
                           (#x47 :scroll-lock)
                           (#x48 :pause)
                           (#x49 :insert)
                           (#x4a :home)
                           (#x4b :page-up)
                           (#x4c :delete)
                           (#x4d :end)
                           (#x4e :page-down)
                           (#x4f :right)
                           (#x50 :left)
                           (#x51 :down)
                           (#x52 :up)
                           (#x53 :num-lock)
                           (#x54 :kp-divide)
                           (#x55 :kp-multiply)
                           (#x56 :kp-subtract)
                           (#x57 :kp-add)
                           (#x58 :kp-enter)
                           (#x59 :kp-1)
                           (#x5a :kp-2)
                           (#x5b :kp-3)
                           (#x5c :kp-4)
                           (#x5d :kp-5)
                           (#x5e :kp-6)
                           (#x5f :kp-7)
                           (#x60 :kp-8)
                           (#x61 :kp-9)
                           (#x62 :kp-0)
                           (#x63 :kp-dot)
                           (#x64 :backslash)
                           (#x65 :application)
                           (#x66 :power)
                           (#x67 :kp-equal)
                           (#x68 :f13)
                           (#x69 :f14)
                           (#x6a :f15)
                           (#x6b :f16)
                           (#x6c :f17)
                           (#x6d :f18)
                           (#x6e :f19)
                           (#x6f :f20)
                           (#x70 :f21)
                           (#x71 :f22)
                           (#x72 :f23)
                           (#x73 :f24)
                           (#x85 :kp-decimal)
                           (#x87 :ro)
                           (#x88 :katakana-hiragana)
                           (#x89 :yen)
                           (#x8a :henkan)
                           (#x8b :muhenkan)
                           (#x8c :kp-decimal-pc98)
                           (#x90 :hangul-english)
                           (#x91 :hanja)
                           (#x92 :katakana)
                           (#x93 :hiragana)
                           (#x94 :zenkaku-hankaku)
                           (#xe0 :left-control)
                           (#xe1 :left-shift)
                           (#xe2 :left-alt)
                           (#xe3 :left-gui)
                           (#xe4 :right-control)
                           (#xe5 :right-shift)
                           (#xe6 :right-alt)
                           (#xe7 :right-gui))
            do (setf (aref array k) v))
      array))

(defun button->keyword (button)
  (case button
    (0 :left)
    (1 :right)
    (2 :middle)
    (3 :x1)
    (4 :x2)
    (T :x3)))

(defun scan-code->keyword (code)
  (or (aref +scan-code-keyword-map+ code) code))

(defun keyword->string (key &key shift)
  (let ((entry (gethash key +keyword-string-map+)))
    (if shift (cdr entry) (car entry))))
